import cv2
import numpy as np

class Camera():
    def __init__(self):
        self.size=(640,480)
        # 创建一个窗口，放置6个滑动条
        cv2.namedWindow("TrackBars")
        cv2.resizeWindow("TrackBars", 640, 240)
        cv2.createTrackbar("Hue Min", "TrackBars", 156, 180, self.empty)#0为默认参数值
        cv2.createTrackbar("Hue Max", "TrackBars", 180, 180, self.empty)
        cv2.createTrackbar("Sat Min", "TrackBars", 43, 255, self.empty)
        cv2.createTrackbar("Sat Max", "TrackBars", 255, 255, self.empty)
        cv2.createTrackbar("Val Min", "TrackBars", 46, 255, self.empty)
        cv2.createTrackbar("Val Max", "TrackBars", 255, 255, self.empty)

    # 滑动条的回调函数，获取滑动条位置处的值
    def empty(self,a):
        self.h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
        self.h_max = cv2.getTrackbarPos("Hue Max", "TrackBars")
        self.s_min = cv2.getTrackbarPos("Sat Min", "TrackBars")
        self.s_max = cv2.getTrackbarPos("Sat Max", "TrackBars")
        self.v_min = cv2.getTrackbarPos("Val Min", "TrackBars")
        self.v_max = cv2.getTrackbarPos("Val Max", "TrackBars")
        return self.h_min, self.h_max, self.s_min, self.s_max, self.v_min, self.v_max

    def detector(self,img):
    	#####################
    	##首先该目标放置位置在中心，获取中心点的hsv参数，来滤除其余颜色特征
    	#####################
        img=cv2.resize(img,self.size)
        frame=img.copy()
        imgHSV = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        # 调用回调函数，获取滑动条的值
        h_min, h_max, s_min, s_max, v_min, v_max = self.empty(0)
        lower = np.array([h_min, s_min, v_min])
        upper = np.array([h_max, s_max, v_max])
        # 获得指定颜色范围内的掩码
        mask = cv2.inRange(imgHSV, lower, upper)
        # 寻找图中轮廓
        cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2]
        if len(cnts)>0:
            # 找到面积最大的轮廓
            c = max(cnts, key=cv2.contourArea)
        #####################
    	##根据颜色和最大轮廓体积综合判断到底属于哪一类
    	#####################

            # 寻找凸包并绘制凸包（轮廓）
            #hull = cv2.convexHull(c)
            # print(len(hull))
            # length = len(hull)
            # if length > 5:
            #     # 绘制图像凸包的轮廓
            #     for i in range(length):
            #         cv2.line(img, tuple(hull[i][0]), tuple(hull[(i + 1) % length][0]), (0, 0, 255), 2)
            # cv2.imshow('finger', img)
            # 使用最小外接圆圈出面积最大的轮廓
            #((x, y), radius) = cv2.minEnclosingCircle(c)
            rect= cv2.minAreaRect(c)
            box = cv2.boxPoints(rect)
            # 标准化坐标到整数
            box = np.int0(box)#获得四个点
            cv2.drawContours(image, [box], 0, (0, 0, 255), 3)
            ######################
            ##下面利用box求出大小，然后求得c与面积的比例
            ######################
            # 计算轮廓的矩
            #M = cv2.moments(c)
            # 计算轮廓的重心
            #center = (int(M["m10"] / (M["m00"]+1e-07)), int(M["m01"] / (M["m00"]+1e-07)))
            # 只处理尺寸足够大的轮廓
            #if radius > 5 and len(hull)>10:
            #    # 画出最小外接圆
            #    cv2.circle(frame, (int(x), int(y)), int(radius), (0, 255, 255), 2)
            #    # 画出重心
            #    cv2.circle(frame, center, 5, (0, 0, 255), -1)

        # 对原图图像进行按位与的操作，掩码区域保留
        imgResult = cv2.bitwise_and(img, img, mask=mask)

        return frame,mask,imgResult


if __name__ == '__main__':
    camera=Camera()
    path = '1.jpg'
    cap=cv2.VideoCapture(0)
    while (cap.isOpened()):
        ret, frame = cap.read()
        #frame=cv2.imread(path)#测试图片塞入
        frame,mask,result=camera.detector(frame)#识别
        cv2.imshow("Mask", mask)
        cv2.imshow("Result", result)
        cv2.imshow('frame', frame)
        cv2.waitKey(1)